﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Abigail.Ui.Article
{
    public partial class UiEditArticle : Form
    {
        Controller c;
        List<Model.ArticleCategory> categories;
        Model.Article article;
        bool isCreatingNew = false;
        public UiEditArticle(Controller c, List<Model.ArticleCategory> items, string[] unittypes, string[] stockLocationAreas, string[] stockLocationShelf, string[] stockLocationLevel, string[] stockLocationSection)
        {
            InitializeComponent();
            this.c = c;
            this.categories = items;
            buildtree();
            tree_categories.Nodes[0].Expand();
            isCreatingNew = true;
            FillFields(unittypes, stockLocationAreas, stockLocationShelf, stockLocationLevel, stockLocationSection);
            this.Show();
        }

        public UiEditArticle(Controller c, List<Model.ArticleCategory> items, Model.Article article, string[] unittypes, string[] stockLocationAreas, string[] stockLocationShelf, string[] stockLocationLevel, string[] stockLocationSection)
        {
            InitializeComponent();
            this.c = c;
            this.categories = items;
            this.article = article;
            buildtree();
            SetSelected(article.Category.Id);
            FillFields(unittypes, stockLocationAreas, stockLocationShelf, stockLocationLevel, stockLocationSection);
            isCreatingNew = false;
            this.Show();
        }

        private void FillFields(string[] unittypes, string[] stockLocationAreas, string[] stockLocationShelf, string[] stockLocationLevel, string[] stockLocationSection)
        {
            try
            {
                box_type.Items.AddRange(unittypes);
                box_type.SelectedIndex = 0;
                box_stockLocationAreas.Items.AddRange(stockLocationAreas);
                box_stockLocationAreas.SelectedIndex = 0;
                box_stockLocationShelf.Items.AddRange(stockLocationShelf);
                box_stockLocationShelf.SelectedIndex = 0;
                box_stockLocationLevel.Items.AddRange(stockLocationLevel);
                box_stockLocationLevel.SelectedIndex = 0;
                box_stockLocationSection.Items.AddRange(stockLocationSection);
                box_stockLocationSection.SelectedIndex = 0;
                deleteToolStripMenuItem.Enabled = false;
                if (article != null)
                {
                    deleteToolStripMenuItem.Enabled = true;
                    txt_articleId.Text = article.Id.ToString();
                    txt_name.Text = article.Name;
                    txt_amount.Text = article.Amount.ToString();
                    txt_priceExcl.Text = article.Price.ToString();
                    txt_priceIncl.Text = article.PriceIncl.ToString();
                    txt_valueExcl.Text = article.ReplacementCostExcl.ToString();
                    txt_valueIncl.Text = article.ReplacementCostIncl.ToString();
                    txt_height.Text = article.Height.ToString();
                    
                    txt_depth.Text = article.Depth.ToString();
                    txt_width.Text = article.Width.ToString();
                    txt_weight.Text = article.Weight.ToString();
                    txt_volume.Text = article.Volume.ToString();

                    check_stackable.Checked = article.Stackable;
                    check_tiltable.Checked = article.Tiltable;
                    check_wheels.Checked = article.Wheels;

                    #region SetSelected in ComboBoxes
                    int i = 0;
                    while (i < unittypes.Length)
                    {
                        if (unittypes[i] == article.Type)
                            box_type.SelectedIndex = i;
                        i++;
                    }

                    i = 0;
                    while (i < stockLocationAreas.Length)
                    {
                        if (stockLocationAreas[i] == article.StockLocation.Area.Definition)
                            box_stockLocationAreas.SelectedIndex = i;
                        i++;
                    }

                    i = 0;
                    while (i < stockLocationShelf.Length)
                    {
                        if (stockLocationShelf[i] == article.StockLocation.Shelf)
                            box_stockLocationShelf.SelectedIndex = i;
                        i++;
                    }

                    i = 0;
                    while (i < stockLocationLevel.Length)
                    {
                        if (stockLocationLevel[i] == article.StockLocation.Level)
                            box_stockLocationLevel.SelectedIndex = i;
                        i++;
                    }

                    i = 0;
                    while (i < stockLocationSection.Length)
                    {
                        if (stockLocationSection[i] == article.StockLocation.Section)
                            box_stockLocationSection.SelectedIndex = i;
                        i++;
                    }
                    #endregion
                }

                #region Add TextChanged Events to calculate volume
                txt_depth.TextChanged += new EventHandler(CalculateVolume_TextChanged);
                txt_height.TextChanged += new EventHandler(CalculateVolume_TextChanged);
                txt_width.TextChanged += new EventHandler(CalculateVolume_TextChanged);

                txt_priceExcl.Leave += new EventHandler(CalculatePrice_TextChanged);
                txt_priceIncl.Leave += new EventHandler(CalculatePrice_TextChanged);

                txt_valueExcl.Leave += new EventHandler(CalculateReplacementCost_TextChanged);
                txt_valueIncl.Leave += new EventHandler(CalculateReplacementCost_TextChanged);
                #endregion
            }
            catch (Exception e)
            {
                Popup.Error(e.Message.ToString(), e.GetType().ToString());
            }
        }

        #region TreeView
        private TreeNode FindNode(TreeNode givenNode, int id)
        {
            foreach (TreeNode node in givenNode.Nodes)
            {
                if (((Model.ArticleCategory)node.Tag).Id == id)
                {
                    return node;
                }
                else
                {
                    TreeNode nodeChild = FindNode(node, id);
                    if (nodeChild != null) return nodeChild;
                }
            }
            return (TreeNode)null;
        }

        private TreeNode FindBlueNode(TreeNode givenNode)
        {
            foreach (TreeNode node in givenNode.Nodes)
            {
                if (node.ForeColor == Color.Blue)
                {
                    return node;
                }
                else
                {
                    TreeNode nodeChild = FindBlueNode(node);
                    if (nodeChild != null) return nodeChild;
                }
            }
            return (TreeNode)null;
        }

        private void SetSelected(int id)
        {
            if (id == 0)
            {
                tree_categories.SelectedNode = tree_categories.Nodes[0];
                return;
            }
            TreeNode node = tree_categories.Nodes[0];
            node = FindNode(node, id);
            tree_categories.SelectedNode = node;

        }
        private void buildtree()
        {
            tree_categories.Nodes.Clear();    // Clear any existing categories
            tree_categories.BeginUpdate();    // prevent overhead and flicker
            LoadBaseNodes();                  // load all the lowest tree nodes
            tree_categories.EndUpdate();      // re-enable the tree
            tree_categories.Refresh();        // refresh the treeview display
        }

        private void LoadBaseNodes()
        {
            TreeNode baseNode = tree_categories.Nodes.Add("Kategorier"); // add it to the tree
            baseNode.Tag = new Model.ArticleCategory();
            baseNode.Name = "top";

            int baseParent = 0;                 // Find the lowest root category parent value
            TreeNode node;
            foreach (Model.ArticleCategory cat in categories)
            {
                if (cat.MainCategory < baseParent)
                    baseParent = cat.MainCategory;
            }
            foreach (Model.ArticleCategory cat in categories)         // iterate through the categories
            {
                if (cat.MainCategory == baseParent)     // found a matching root item
                {
                    node = baseNode.Nodes.Add(cat.Name); // add it to the tree
                    node.Tag = cat;                 // send the category into the tag for future processing
                    getChildren(node);              // load all the children of this node
                }
            }
        }

        // recursive tree loader. Passes back in a node to retireve its childre
        // until there are no more children for this node.
        private void getChildren(TreeNode node)
        {
            TreeNode Node = null;
            Model.ArticleCategory nodeCat = (Model.ArticleCategory)node.Tag;  // get the category for this node
            foreach (Model.ArticleCategory cat in categories)         // locate all children of this category
            {
                if (cat.MainCategory == nodeCat.Id)     // found a child
                {
                    Node = node.Nodes.Add(cat.Name);    // add the child
                    Node.Tag = cat;                         // set its tag to its category
                    getChildren(Node);                      // find this child's children
                }
            }
        }

        private void tree_categories_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode node = FindBlueNode(tree_categories.Nodes[0]);
            if (node != null)
                node.ForeColor = Color.Black;
            tree_categories.Nodes[0].ForeColor = Color.Black;

            ((TreeView)sender).SelectedNode.ForeColor = Color.Blue;
        }
        #endregion

        #region Menu
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Popup.FunctionNotImplemented();
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Model.Article article = new Model.Article();
                if(txt_articleId.Text.Length != 0)
                    article.Id = int.Parse(txt_articleId.Text);
                if (Sanitize.BetweenLength(txt_name.Text, 2, 60))
                    article.Name = txt_name.Text;
                else
                {
                    Popup.Information("Benämingen är för kort");
                    return;
                }
                if (txt_priceExcl.Text.Length != 0)
                    article.Price = decimal.Parse(txt_priceExcl.Text);
                if (txt_valueExcl.Text.Length != 0)
                    article.ReplacementCostExcl = decimal.Parse(txt_valueExcl.Text);
                article.Stackable = check_stackable.Checked;
                article.StockLocation = c.GetStockLocation(box_stockLocationAreas.SelectedItem.ToString(), box_stockLocationShelf.SelectedItem.ToString(), box_stockLocationLevel.SelectedItem.ToString(), box_stockLocationSection.SelectedItem.ToString());
                if (article.StockLocation == null)
                {
                    Popup.Information("Ogiltig lagerplats");
                    return;
                }
                
                article.Tiltable = check_tiltable.Checked;
                article.Type = box_type.SelectedItem.ToString();
                if (txt_weight.Text.Length != 0)
                    article.Weight = decimal.Parse(txt_weight.Text);
                article.Wheels = check_wheels.Checked;
                if (txt_width.Text.Length != 0)
                    article.Width = decimal.Parse(txt_width.Text);
                if (txt_amount.Text.Length != 0)
                    article.Amount = decimal.Parse(txt_amount.Text);
                if (tree_categories.SelectedNode == null)
                {
                    Popup.Information("Du måste välja en kategori");
                    return;
                }
                if (tree_categories.SelectedNode == tree_categories.Nodes[0])
                {
                    Popup.Information("Du kan inte välja att spara en artikel i denna kategori.");
                    return;
                }
                article.Category = ((Model.ArticleCategory)tree_categories.SelectedNode.Tag);
                if (txt_depth.Text.Length != 0)
                    article.Depth = decimal.Parse(txt_depth.Text);
                if (txt_height.Text.Length != 0)
                    article.Height = decimal.Parse(txt_height.Text);

                if (isCreatingNew)
                {
                    if (c.SaveNewArticle(article))
                    {
                        Popup.Information("Din artikel sparades i databasen\n\nDetta fönster kommer nu att stängas.\nOm du vill redigera artikeln så måste du öppna den på nytt.");
                        this.Close();
                    }
                }
                else
                {
                    if (c.UpdateArticle(article))
                    {
                        Popup.Information("Din artikel uppdaterades i databasen");
                    }
                }
            }
            catch (Exception ex)
            {
                Popup.Error(ex.ToString(), ex.GetType().ToString());
            }


           
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Popup.QuestionYesNo("Är du säker på att du vill radera artikelnummer" + txt_articleId.Text, "Är du säker?", "warning"))
            {
                try
                {
                    c.DeleteArticle(this, int.Parse(txt_articleId.Text));
                }
                catch (Exception ex)
                {
                    Popup.Error(ex);
                } 
            }
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion

        #region Event Verifiers
        // This event occurs after the KeyDown event and can be used to prevent
        // characters from entering the control.
        private void VerifyDecimal_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            // Check for valid input, or ignore
            if (!char.IsPunctuation(e.KeyChar) && !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
                e.Handled = true; // Stop the character from being entered into the control since it is not wanted.

            if (char.IsPunctuation(e.KeyChar) || e.KeyChar == (Char)44)
            {
                if (((TextBox)sender).Text.Contains((Char)44))
                    e.Handled = true;
                else
                    e.KeyChar = (Char)44;
            }
        }

        // This event occurs after the KeyDown event and can be used to prevent
        // characters from entering the control.
        private void VerifyName_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            // Check for valid input, or ignore
            if (!char.IsLetterOrDigit(e.KeyChar) && !char.IsControl(e.KeyChar) && !char.IsWhiteSpace(e.KeyChar))
                e.Handled = true; // Stop the character from being entered into the control since it is not wanted.
        }

        private void CalculateVolume_TextChanged(object sender, EventArgs e)
        {
            try
            {
                //Avoid parse error
                if (((TextBox)sender).Text == "")
                {
                    txt_volume.Text = "0";
                    return;
                }
                
                decimal height = decimal.Parse(txt_height.Text);
                decimal width = decimal.Parse(txt_width.Text);
                decimal depth = decimal.Parse(txt_depth.Text);

                //Avoid divide by zero
                if (height == 0 || width == 0 || depth == 0)
                {
                    txt_volume.Text = "0";
                    return;
                }

                txt_volume.Text = Math.Round(decimal.Divide((decimal.Multiply((decimal.Multiply(height, width)), depth)), 1000000), 3).ToString();
            }
            catch (Exception)
            {
                Popup.Error("Lyckades inte räkna ut volymen.\nHar du några konstiga tecken i fälten?");
            }
        }

        private void VerifyDecimal_TextChanged(object sender, EventArgs e)
        {
            try
            {
                ((TextBox)sender).Text = Math.Round(decimal.Parse(((TextBox)sender).Text), 2).ToString();
            }
            catch (Exception)
            {
                ((TextBox)sender).Text = "0,00";
            }
        }

        private void CalculatePrice_TextChanged(object sender, EventArgs e)
        {
            try
            {
                if (((TextBox)sender).Name == txt_priceExcl.Name)
                {
                    //Avoid parse error
                    if (((TextBox)sender).Text == "")
                    {
                        txt_priceIncl.Text = "0";
                        return;
                    }

                    decimal priceExcl = decimal.Parse(((TextBox)sender).Text);
                    txt_priceIncl.Text = Math.Round((decimal.Multiply(priceExcl, new decimal(1.25))), 2).ToString();
                }
                else if (((TextBox)sender).Name == txt_priceIncl.Name)
                {
                    //Avoid parse error
                    if (((TextBox)sender).Text == "")
                    {
                        txt_priceExcl.Text = "0";
                        return;
                    }

                    decimal priceIncl = decimal.Parse(((TextBox)sender).Text);
                    txt_priceExcl.Text = Math.Round((decimal.Multiply(priceIncl, new decimal(0.8))), 2).ToString();
                }
            }
            catch (Exception)
            {
                Popup.Error("Lyckades inte räkna ut priset.\nHar du några konstiga tecken i fälten?");
            }
        }

        private void CalculateReplacementCost_TextChanged(object sender, EventArgs e)
        {
            try
            {
                if (((TextBox)sender).Name == txt_valueExcl.Name)
                {
                    ////Avoid parse error
                    //if (((TextBox)sender).Text == "")
                    //{
                    //    txt_valueIncl.Text = "0";
                    //    return;
                    //}

                    decimal valueExcl = decimal.Parse(((TextBox)sender).Text);
                txt_valueIncl.Text = Math.Round((decimal.Multiply(valueExcl, new decimal(1.25))), 2).ToString();
                }
                else if (((TextBox)sender).Name == txt_valueIncl.Name)
                {
                    ////Avoid parse error
                    //if (((TextBox)sender).Text == "")
                    //{
                    //    txt_valueExcl.Text = "0";
                    //    return;
                    //}

                    decimal valueIncl = decimal.Parse(((TextBox)sender).Text);
                    txt_valueExcl.Text = Math.Round((decimal.Multiply(valueIncl, new decimal(0.8))), 2).ToString();
                }
            }
            catch (Exception)
            {
                Popup.Error("Lyckades inte räkna ut priset.\nHar du några konstiga tecken i fälten?");
            }
        }
        #endregion
    }
}
